package com.my.house.common;

import com.my.house.common.utils.JsonUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.time.format.DateTimeParseException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yangll
 */
@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(DateTimeParseException.class)
    public ApiResult<Void> handleDateTimeParseException(HttpServletRequest request, DateTimeParseException ex) {
        String message = ex.getMessage();
        String parsedString = ex.getParsedString();
        log.error("{}, 日期转换异常：{}。", request.getRequestURI(), message);
        return ApiResult.error("日期转换异常" + parsedString);
    }

    @ExceptionHandler({BindException.class, MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    public ApiResult<Void> handleMethodArgumentNotValidException(HttpServletRequest request, BindException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        Map<String, String> map = new HashMap<>(bindingResult.getErrorCount() + bindingResult.getFieldErrorCount());
        ObjectError objectError = bindingResult.getGlobalError();
        if (objectError != null) {
            map.put("_global", objectError.getDefaultMessage());
        }
        for (FieldError error : bindingResult.getFieldErrors()) {
            String field = error.getField();
            map.put(field, error.getDefaultMessage());
        }
        log.error("{}, 方法参数校验失败：{}。", request.getRequestURI(), map);
        return ApiResult.error("方法参数校验失败" + JsonUtils.easyToJsonString(map));
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public ApiResult<Void> handleMissingServletRequestParameterException(HttpServletRequest request, MissingServletRequestParameterException ex) {
        log.error("{}, 缺少必要的参数：{}", request.getRequestURI(), ex.getParameterName());
        Object[] args = {ex.getParameterName()};
        return ApiResult.error("缺少必要的参数" + JsonUtils.easyToJsonString(args));
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseStatus(HttpStatus.OK)
    public ApiResult<Void> handleMethodArgumentTypeMismatchException(HttpServletRequest request, MethodArgumentTypeMismatchException ex) {
        log.error("{}, 参数类型转换失败：{}", request.getRequestURI(), ex.getName());
        Object[] args = {ex.getName()};
        return ApiResult.error("参数类型转换失败" + JsonUtils.easyToJsonString(args));
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult<Void> handleHttpMessageNotReadableException(HttpServletRequest request, HttpMessageNotReadableException ex) {
        log.error("{}, 请求数据非法：", request.getRequestURI(), ex);
        return ApiResult.error("请求数据非法");
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public ApiResult<Void> handleHttpRequestMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) {
        log.error("{}, 不支持的请求方式：", request.getRequestURI(), ex);
        return ApiResult.error("不支持的请求方式");
    }

//    @ResponseStatus(HttpStatus.OK)
//    @ExceptionHandler(BizException.class)
//    public ApiResult<Void> handleAttendException(HttpServletRequest request, BizException exception) {
//        log.error("{}, 业务异常：", request.getRequestURI(), exception);
//        return ApiResult.of(exception.getCode(), exception.getMessage(), null);
//    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ApiResult<Void> handleException(HttpServletRequest request, Exception ex) {
        log.error("{}, 发生异常：", request.getRequestURI(), ex);
        return ApiResult.error(BizException.system().getMessage());
    }
}
